package com.icedata.sika.bridge

import net.mamoe.mirai.event.events.MessageEvent
import net.mamoe.mirai.message.data.*
import java.util.*

/**
 * # Sika的消息链
 * Sika所有的输入、输出的消息都是使用 [SikaMessageChain] 的实例来表示的
 *
 * [SikaMessageChain] 的输入消息实例由Sika接管，用户无需关心实现
 *
 * [SikaMessageChain] 的输出消息必须要使用 [SikaMessageChainBuilder] 的实例来构造，不允许直接使用 [SikaMessageChain] 的构造方法
 *
 * [SikaMessageChainBuilder] 支持使用DSL语法构造 [SikaMessageChain]
 *
 * # 内容
 * [SikaMessageChain] 是一个 [LinkedList]，它是元素 [SikaSingleMessage] 的有序集合
 *
 * [SikaMessageChainBuilder] 构造 [SikaMessageChain] 的时候，将 [SikaSingleMessage] 放入即可
 * */
class SikaMessageChain constructor(val miraiMessageChain: MessageChain) : LinkedList<SikaSingleMessage>() {

    internal constructor() : this(messageChainOf())

    operator fun SikaSingleMessage.unaryPlus() {
        this@SikaMessageChain.add(this)
    }

    operator fun String.unaryPlus() {
        this@SikaMessageChain.add(SikaPlainMessage(this))
    }

    init {
        miraiMessageChain.forEach {
            when (it) {
                is PlainText -> {
                    this.add(SikaPlainMessage(it.content))
                    hasPlainMessage = true
                }
                is QuoteReply -> {
                    this.add(SikaQuoteMessage(it))
                    hasQuoteMessage = true
                }
                is Image -> {
                    this.add(SikaImageMessage(it))
                    hasImageMessage = true
                }
                is Face -> {
                    this.add(SikaFaceMessage(it))
                    hasFaceMessage = true
                }
                is At -> {
                    this.add(SikaAtMessage(it))
                    hasAtMessage = true
                }
            }
        }
    }

    constructor(messageEvent: MessageEvent) : this(messageEvent.message)

    var hasAtMessage: Boolean = false
    var hasPlainMessage: Boolean = false
    var hasImageMessage: Boolean = false
    var hasFaceMessage: Boolean = false
    var hasQuoteMessage: Boolean = false

    @UserSikaAPI
    fun contentToString(): String {
        var string = ""
        this.forEach {
            string += it.contentToString()
        }
        return string
    }

    @MiraiBasedAPI
    override fun toString(): String {
        var string = ""
        this.forEach {
            string = string.plus(it.toString())
        }
        return string
    }
}

class SikaMessageChainBuilder : LinkedList<SikaSingleMessage>() {
    fun build(): SikaMessageChain {
        val messageChainBuilder = MessageChainBuilder()
        this.forEach {
            messageChainBuilder.add(it.miraiMessage)
        }
        return SikaMessageChain(messageChainBuilder.build())
    }

    fun add(message: String) {
        add(SikaPlainMessage(message))
    }
}

@Deprecated("该API当前出现严重问题", ReplaceWith("SikaMessageBuilder"))
fun sikaMessageChain(block: SikaMessageChain.() -> Unit): SikaMessageChain {
    return SikaMessageChain().apply {
        block()
        val messageChainBuilder = MessageChainBuilder()
        this.forEach {
            messageChainBuilder.add(it.miraiMessage)
        }
        miraiMessageChain.plus(messageChainBuilder.build())
    }
}